Skip to content

fix(dispatcher): improve fanout delivery timeouts and retry budget#3270

Open
migmartri wants to merge 3 commits into
chainloop-dev:mainfrom
migmartri:dw/5173-1783416967
Open

fix(dispatcher): improve fanout delivery timeouts and retry budget#3270
migmartri wants to merge 3 commits into
chainloop-dev:mainfrom
migmartri:dw/5173-1783416967

Conversation

@migmartri

@migmartri migmartri commented Jul 7, 2026

Copy link
Copy Markdown
Member

Changes

  • Bump MaxElapsedTime from 10s to 5m: ~12-15 retry attempts with the existing exponential backoff, enough to ride out transient blips without leaking goroutines in the fire-and-forget dispatch model.
  • Add per-attempt timeout (10s): each Execute call now runs under context.WithTimeout so a single hung HTTP request cannot consume the entire retry budget.
  • Set http.Client.Timeout on the webhook plugin: matches the dispatcher's per-attempt deadline via a shared sdk.PerAttemptTimeout constant.
  • Wrap backoff with parent context: backoff.WithContext ensures the retry loop stops promptly on parent context cancellation.
  • Bump webhook plugin version 1.1 → 1.2: reflects the new per-attempt timeout behavior.
  • Replace deprecated io/ioutil with io in the webhook plugin.

Closes #3269
Refs #39

Assisted-by: OpenCode

🤖 Posted by Maximus bot (OpenCode) on behalf of @migmartri

- Bump MaxElapsedTime from 10s to 5m (~12-15 retry attempts)
- Add per-attempt context.WithTimeout (10s) so a single hung HTTP
  request cannot consume the entire retry budget
- Set http.Client.Timeout on the webhook plugin to match the
  per-attempt deadline (shared via sdk.PerAttemptTimeout)
- Wrap backoff with backoff.WithContext so the retry loop stops
  promptly when the parent context is cancelled
- Replace deprecated io/ioutil with io in the webhook plugin

Refs chainloop-dev#3269
Closes chainloop-dev#39

Assisted-by: OpenCode
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>

Chainloop-Trace-Sessions: ses_0c4100537ffeM74j5m1U4O10fe
@chainloop-platform

chainloop-platform Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

AI Session Analysis

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟡 60% 1 ✅ 0 100% AI / 0% Human 2 +8 / -0 24m37s

🟡 60% — 100% AI — ✅ All policies passing

Jul 7, 2026 09:36 UTC · 24m37s · $2.30 · 367.0k in / 22.8k out · opencode 1.17.14 (z-ai/glm-5.2)

View session details ↗

Change Summary

  • Raises dispatcher retry budget from 10s to 5m and adds per-attempt timeouts.
  • Shares the timeout constant across SDK/webhook code and adds dispatcher retry and cancellation tests.
  • Bumps webhook plugin version to 1.2 and updates assisted-by wording guidance in docs.

AI Session Overall Score

🟡 60% — Strong implementation, but repeated AI-attribution drift kept the session out of green.

AI Session Analysis Breakdown

🟢 88% · solution-quality

🟢 AI addressed root causes like parent-context cancellation instead of papering over symptoms. · High Impact

🟢 86% · context-and-planning

🟢 AI grounded the change in repo code and staged the work before editing. · High Impact

🟢 84% · scope-discipline

No notes.

🟡 72% · verification

🟢 AI added focused dispatcher tests and reran go test after fixes. · High Impact

🟠 Dispatcher tests were run repeatedly, but the transcript does not show equally direct validation of the webhook-timeout behavior. · Medium Severity

💡 For multi-component changes, capture one concrete validation step per changed behavior before summarizing the work as done.

🟡 68% · user-trust-signal

No notes.

🔴 35% · alignment

🔴 AI misattributed the session twice before the user steered it from Claude Code to OpenCode; user-trust flagged the same late correction cluster. · High Severity

💡 Verify the exact AI-tool label once before rewriting commits, PR bodies, and issue text so naming corrections do not cascade.


File Attribution

████████████████████ 100% AI / 0% Human

Status Attribution File Lines
modified ai AI_POLICY.md +5 / -0
modified ai CLAUDE.md +3 / -0

Policies (4)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-ses-0c -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-ses-0c -
✅ Passed ai-config-no-secrets ai-coding-session-ses-0c -
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-ses-0c -

Powered by Chainloop and Chainloop Trace

Reflects the new per-attempt HTTP timeout behavior introduced in the
previous commit.

Assisted-by: OpenCode
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>

Chainloop-Trace-Sessions: ses_0c4100537ffeM74j5m1U4O10fe
@migmartri migmartri force-pushed the dw/5173-1783416967 branch from 00441fb to e16b9b2 Compare July 7, 2026 09:59
Add OpenCode to the examples and state explicitly that the value must
match the tool that produced the work, not the underlying model, and
must not be copied blindly from an example.

Assisted-by: OpenCode
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>

Chainloop-Trace-Sessions: ses_0c4100537ffeM74j5m1U4O10fe
@migmartri migmartri requested a review from a team July 7, 2026 15:29

@waveywaves waveywaves left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few inline questions focused on keeping the fix tight and matching existing timeout patterns.

// set their http.Client.Timeout to this value so a hung endpoint cannot
// consume the entire retry budget in a single attempt — the cutoff is
// enforced at whichever layer sees the stall first.
const PerAttemptTimeout = 10 * time.Second

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this stay out of the SDK? This makes control-plane retry policy part of the plugin SDK API. A local dispatcher/webhook timeout constant is boring duplication, but avoids coupling external plugin authors to this value.

logger.Infow("msg", "executing integration", "integration", plugin.String(), "input", inputType)

err := plugin.Execute(ctx, opts)
err := plugin.Execute(attemptCtx, opts)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only bounds plugins that honor the context. webhook does, but dependency-track currently ignores ctx and uses http.DefaultClient without a timeout, so this isn't a universal fanout attempt timeout yet. Should we update that plugin too or narrow the claim?

return err
},
b,
backoff.WithContext(b, ctx),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good, but the production caller currently uses dispatcher.Run(context.TODO(), ...), so cancellation won't fire there. Should the caller pass a real parent/app context, or should we avoid claiming production cancellation is fixed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve fanout webhook delivery timeouts and retry budget

2 participants